<?php
namespace kernel\library;

use Workerman\Protocols\Http\Response;

class Http
{
    //运行
    public function run($request){
        //调用路由
        try {
            $next = $this->controller($request);//拿到控制器Closure 类
            $data = $this->response($next);
        } catch (\Exception $e) {
            $data = Handler::exception($e);
        }
        $response = new Response($data['status'], $data['headers'], $data['body']);// 初始化并设置值
        // 设置cookie 
        foreach($data['cookies'] as $k => $v){
            $response->cookie($k, $v);
        }
        return $response;
    }

    /**
     * .拿到控制器 Closure 类
     *
     * @param
     *            $path
     * @param
     *            $data
     * @return
     */
    protected function controller($request)
    {
        $path = $request->path();
        
        $staticFile = Env::get('BASICS_PATH').'public'.$path;
        if(file_exists($staticFile)){
            if(is_dir($staticFile)){
                if(file_exists($staticFile.'/index.html') == false){
                    return '403错误';
                }
                return $staticFile.'/index.html';
            }else{
                //文件类型发送的header是不一样的
                return $staticFile;
            }
        }
        //判断一下静态文件是否存在
        
        $method = $request->method();
        $data   = $request->post() + $request->get();
        $cookie = $request->cookie(); 
        $route      = self::getRoute($path);
        $routeClass = explode('@', $route[1]);
        
        $calss = Env::get('BASICS_PATH') . 'app' . DIRECTORY_SEPARATOR . 'http' . DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $routeClass[0]) . '.php';
        if (! file_exists($calss)) {
            Error::setError($calss . ' file does not exist', 500);
        }
        
        //请求方法
        if(!in_array($method, $route[0])){
            Error::setError($method.' request is not supported ', 500);
        }
        
        global $request,$classMethod;
        //请求对象
        $request = Request::getInstance();
        $request->path = '';//清空
        $request->method = '';
        $request->param = [];//清空
        $request->cookie = [];//清空
        $request->setParam($data);
        $request->setCookie($cookie);
        $request->setPath($path);
        $request->setMethod($method);
        
        $controllerClass = '\\app\\http\\controller\\' . $routeClass[0];
        
        $classMethod  = $routeClass[1];
       
        
        //先验证全局中间件
        $middlewares = Config::get('middleware.middleware');
        foreach($middlewares as $v){
            (new $v())->handle($request);
        }
        
        //路由中间件
        $routeMiddleware = $route[2];
        foreach($routeMiddleware as $v){
            $middlewareClass = Config::get('middleware.route.'.$v);
            (new $middlewareClass())->handle($request);
        }
        
        $next = (new $controllerClass())->$classMethod($request);
        
        unset($classMethod, $request);
        return $next;
    }
    
    /**
     * .返回响应格式
     * @param  $data
     * @param  $reData
     * @return string
     */
    protected function response($data){
        if(is_array($data)){
            //返回json
            $data = \kernel\library\Response::json($data);
        }else{
            //判断是否是文件
            $header = [];
            if(file_exists($data)){
                if(strrpos($data, '.css')){
                    $header = [
                        'Content-Type' => 'text/css'
                    ];
                }elseif(strrpos($data, '.js')){
                    $header = [
                        'Content-Type' => 'text/javascript'
                    ];
                }elseif(strrpos($data, '.jpg')){
                    $header = [
                        'Content-Type' => 'image/jpeg'
                    ];
                }elseif(strrpos($data, '.png')){
                    $header = [
                        'Content-Type' => 'image/png'
                    ];
                }elseif(strrpos($data, '.gif')){
                    $header = [
                        'Content-Type' => 'image/gif'
                    ];
                }elseif(strrpos($data, '.html')){
                    $header = [
                        'Content-Type' => 'text/html; charset=utf-8'
                    ];
                }
                $data = file_get_contents($data);
                
            }
            $data = \kernel\library\Response::string($data, 200, $header);
        }
        return $data;
    }
    
    
    /**
     * .设置路由
     * @param array $methods
     * @param string $uri
     * @param string $action
     * @param array $middleware
     */
    public static $routeList = [];
    public static function setRoute(array $methods, string $uri, ?string $action = null, array $middleware = []){
        self::$routeList[$uri] = [
            $methods,
            $action,
            $middleware
        ];
    }
    
    /**
     * .获取路由
     * @param string $uri
     * @return array|mixed
     */
    public static function getRoute(string $uri){
        if(isset(self::$routeList[$uri])){
            return self::$routeList[$uri];
        }
        
        $uris = explode('/', $uri);
        foreach ($uris as $k => $v){
            $suri = str_replace($uris[count($uris) - ($k+1)], '*', $uri);
            if(isset(self::$routeList[$suri])){
                return self::$routeList[$suri];
            }
        }
        
        Error::setError("路由地址不存在", 404);
    }
    
    /**
     *. 获取全部路由
     * @return array
     */
    public static function getAllRoute(){
        return self::$routeList;
    }
    
    /**
     * .情况路由
     */
    public static function cleanRoute(){
        self::$routeList = [];
    }
}

